package server

import (
	"fmt"
	"log"
	"net"
	"net/http"
	"net/rpc"
	"strings"
	"sync"
)

// RPCService 提供RPC服务
type RPCService struct {
	server *Server
}

// MessageArgs RPC消息参数
type MessageArgs struct {
	ClientID string
	Message  []byte
}

// MessageReply RPC消息响应
type MessageReply struct {
	Success bool
	Error   string
}

// SendMessage 发送消息到客户端
func (s *RPCService) SendMessage(args *MessageArgs, reply *MessageReply) error {
	// 尝试发送消息到本地客户端
	err := s.server.sendToLocalClient(args.ClientID, args.Message)
	if err != nil {
		reply.Success = false
		reply.Error = err.Error()
		return nil // 返回nil表示RPC调用成功，但业务逻辑失败
	}

	reply.Success = true
	return nil
}

// StartRPCServer 启动RPC服务器
func StartRPCServer(server *Server, addr string) error {
	// 创建RPC服务
	rpcService := &RPCService{server: server}

	// 注册RPC服务
	rpc.Register(rpcService)
	rpc.HandleHTTP()

	// 解析地址
	host, port, err := parseAddr(addr)
	if err != nil {
		return err
	}

	// 监听TCP端口
	l, err := net.Listen("tcp", fmt.Sprintf("%s:%s", host, port))
	if err != nil {
		return err
	}

	// 启动HTTP服务器
	go http.Serve(l, nil)

	log.Printf("RPC server started on %s", addr)
	return nil
}

// RPCClient RPC客户端
type RPCClient struct {
	client *rpc.Client
}

// NewRPCClient 创建RPC客户端
func NewRPCClient(addr string) (*RPCClient, error) {
	client, err := rpc.DialHTTP("tcp", addr)
	if err != nil {
		return nil, err
	}

	return &RPCClient{client: client}, nil
}

// SendMessage 发送消息到远程服务器
func (c *RPCClient) SendMessage(clientID string, message []byte) error {
	args := &MessageArgs{
		ClientID: clientID,
		Message:  message,
	}

	reply := &MessageReply{}

	err := c.client.Call("RPCService.SendMessage", args, reply)
	if err != nil {
		return err
	}

	if !reply.Success {
		return fmt.Errorf("remote error: %s", reply.Error)
	}

	return nil
}

// Close 关闭RPC客户端
func (c *RPCClient) Close() error {
	return c.client.Close()
}

// RPCClientPool RPC客户端连接池
type RPCClientPool struct {
	clients     map[string]*RPCClient
	clientsLock sync.RWMutex
}

// NewRPCClientPool 创建RPC客户端连接池
func NewRPCClientPool() *RPCClientPool {
	return &RPCClientPool{
		clients: make(map[string]*RPCClient),
	}
}

// GetClient 获取RPC客户端
func (p *RPCClientPool) GetClient(addr string) (*RPCClient, error) {
	// 检查是否是当前服务器的地址
	// 注意：这个检查在这里不起作用，因为我们已经在SendToClient中做了检查
	// 但保留这个检查作为额外的安全措施

	p.clientsLock.RLock()
	client, exists := p.clients[addr]
	p.clientsLock.RUnlock()

	if exists {
		return client, nil
	}

	// 创建新的客户端
	client, err := NewRPCClient(addr)
	if err != nil {
		return nil, err
	}

	// 添加到连接池
	p.clientsLock.Lock()
	p.clients[addr] = client
	p.clientsLock.Unlock()

	return client, nil
}

// Close 关闭所有RPC客户端
func (p *RPCClientPool) Close() {
	p.clientsLock.Lock()
	defer p.clientsLock.Unlock()

	for addr, client := range p.clients {
		if err := client.Close(); err != nil {
			log.Printf("Failed to close RPC client for %s: %v", addr, err)
		}
	}

	p.clients = make(map[string]*RPCClient)
}

// parseAddr 解析地址
func parseAddr(addr string) (string, string, error) {
	parts := strings.Split(addr, ":")
	if len(parts) != 2 {
		return "", "", fmt.Errorf("invalid address format: %s", addr)
	}

	host := parts[0]
	port := parts[1]

	return host, port, nil
}

// extractPort 从地址中提取端口
func extractPort(addr string) (string, error) {
	_, port, err := parseAddr(addr)
	if err != nil {
		return "", err
	}

	return port, nil
}
